package models

import (
	"database/sql"
	"errors"
	"fmt"
	"image-server/config"
	"image-server/dao/model"
	util "image-server/utils"
)

// CreateAlbum 创建相册（含事务处理和OSS操作）
func CreateAlbum(userID int64, wpsID string, album *model.Album) (int64, error) {
	// 1. 开启数据库事务
	tx, err := config.DB.Begin()
	if err != nil {
		return 0, fmt.Errorf("开启事务失败: %w", err)
	}
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 2. 插入相册基本信息
	result, err := tx.Exec(
		`INSERT INTO albums (user_id, name, description, is_public, created_at, folder_path) 
		VALUES (?, ?, ?, ?, NOW(), ?)`,
		album.UserID, album.Name, album.Description, album.IsPublic,
		"/default/albums", // 默认路径
	)
	if err != nil {
		tx.Rollback()
		return 0, fmt.Errorf("插入数据库失败: %w", err)
	}

	// 3. 获取自增ID并生成OSS路径
	album.ID, _ = result.LastInsertId()
	album.FolderPath, err = util.GenerateUserAlbumFolder(userID, wpsID, album.Name)
	if err != nil {
		tx.Rollback()
		return 0, fmt.Errorf("生成OSS路径失败: %w", err)
	}

	// 4. 更新相册的OSS路径
	_, err = tx.Exec(
		"UPDATE albums SET folder_path = ? WHERE id = ?",
		album.FolderPath, album.ID,
	)
	if err != nil {
		tx.Rollback()
		return 0, fmt.Errorf("更新OSS路径失败: %w", err)
	}

	// 5. 提交事务
	if err := tx.Commit(); err != nil {
		return 0, fmt.Errorf("提交事务失败: %w", err)
	}

	// 6. 创建OSS文件夹
	if err := util.CreateOSSFolder(album.FolderPath); err != nil {
		// 补偿机制：OSS创建失败时删除数据库记录
		config.DB.Exec("DELETE FROM albums WHERE id = ?", album.ID)
		return 0, fmt.Errorf("创建OSS文件夹失败: %w", err)
	}

	// 7. 设置OSS访问权限
	if err := util.SetOSSFolderACL(album.FolderPath, album.IsPublic); err != nil {
		return album.ID, fmt.Errorf("设置ACL权限警告: %w", err) // 非致命错误
	}

	return album.ID, nil
}

// GetAlbumByID 根据ID查询相册
func GetAlbumByID(id int64) (*model.Album, error) {
	var album model.Album
	var isPublic int // 数据库中用int存储bool值

	// 查询相册信息
	err := config.DB.QueryRow(
		`SELECT id, user_id, name, description, is_public, folder_path, created_at 
		 FROM albums WHERE id = ?`,
		id,
	).Scan(
		&album.ID, &album.UserID, &album.Name, &album.Description, &isPublic,
		&album.FolderPath, &album.CreatedAt,
	)
	if err == sql.ErrNoRows {
		return nil, errors.New("相册不存在")
	}
	if err != nil {
		return nil, fmt.Errorf("查询失败: %w", err)
	}

	// 转换bool值（数据库中1表示true，0表示false）
	album.IsPublic = isPublic == 1
	return &album, nil
}

// UpdateAlbum 更新相册信息（含图片路径同步）
func UpdateAlbum(album *model.Album, wpsId string) error {
	fmt.Println("hello")
	// 开启事务（确保相册和图片更新的原子性）
	tx, err := config.DB.Begin()
	if err != nil {
		return fmt.Errorf("开启事务失败: %w", err)
	}
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()

	// 1. 查询旧相册信息
	oldAlbum, err := GetAlbumByID(album.ID)
	fmt.Println("旧：", oldAlbum)
	if err != nil {
		tx.Rollback()
		return err
	}

	// 2. 如果相册名称变更，处理路径更新和OSS文件夹重命名
	var newFolderPath string
	if album.Name != oldAlbum.Name {
		// 生成新的文件夹路径
		newFolderPath, err = util.GenerateUserAlbumFolder(oldAlbum.UserID, wpsId, album.Name)
		if err != nil {
			tx.Rollback()
			return fmt.Errorf("生成新文件夹路径失败: %w", err)
		}
		// 调用OSS工具类重命名远程文件夹
		if err := util.RenameOSSFolder(oldAlbum.FolderPath, newFolderPath); err != nil {
			tx.Rollback()
			return fmt.Errorf("重命名OSS文件夹失败: %w", err)
		}
		// 批量更新该相册下所有图片的OSS路径（替换旧文件夹路径为新路径）
		_, err = tx.Exec(`
			UPDATE images 
			SET 
				oss_key = REPLACE(oss_key, ?, ?),
				thumb_oss_key = CASE 
					WHEN thumb_oss_key IS NOT NULL THEN REPLACE(thumb_oss_key, ?, ?)
					ELSE NULL 
				END
			WHERE album_id = ?
		`, oldAlbum.FolderPath, newFolderPath, oldAlbum.FolderPath, newFolderPath, oldAlbum.ID)
		if err != nil {
			tx.Rollback()
			return fmt.Errorf("更新图片OSS路径失败: %w", err)
		}

		// 更新相册的文件夹路径
		album.FolderPath = newFolderPath
	}
	// 3. 更新相册表信息（后续逻辑不变）
	_, err = tx.Exec(`
		UPDATE albums 
		SET name = ?, description = ?, is_public = ?, folder_path = ?
		WHERE id = ? AND user_id = ?
	`, album.Name, album.Description, album.IsPublic, album.FolderPath, album.ID, album.UserID)
	if err != nil {
		tx.Rollback()
		return fmt.Errorf("更新相册信息失败: %w", err)
	}

	// 4. 同步OSS权限（若权限变更）
	if oldAlbum.IsPublic != album.IsPublic {
		fmt.Println("helloworld")
		if err := util.SetOSSFolderACL(album.FolderPath, album.IsPublic); err != nil {
			tx.Rollback()
			return fmt.Errorf("同步OSS权限失败: %w", err)
		}
	}

	// 提交事务
	if err := tx.Commit(); err != nil {
		tx.Rollback()
		return fmt.Errorf("提交事务失败: %w", err)
	}
	return nil
}

// DeleteAlbumByID 删除相册（含OSS文件）
func DeleteAlbumByID(id, userID int64) error {
	// 1. 查询相册信息
	album, err := GetAlbumByID(id)
	if err != nil {
		return fmt.Errorf("相册id有误")
	}

	// 2. 权限校验
	if album.UserID != userID {
		return fmt.Errorf("不是登录用户")
	}

	// 3. 删除OSS文件夹
	if err := util.DeleteOSSFolder(album.FolderPath); err != nil {
		return fmt.Errorf("删除OSS文件夹失败: %w", err)
	}

	// 4. 删除数据库记录
	_, err = config.DB.Exec(
		"DELETE FROM albums WHERE id = ? AND user_id = ?",
		id, userID,
	)
	if err != nil {
		return fmt.Errorf("删除数据库记录失败: %w", err)
	}

	return nil
}

// GetAlbumsByUserID 分页查询用户相册
func GetAlbumsByUserID(userID int64, page, limit int) ([]model.Album, int64, error) {
	offset := (page - 1) * limit

	// 1. 查询相册列表
	rows, err := config.DB.Query(
		`SELECT id, user_id, name, description, is_public, folder_path, created_at 
		 FROM albums WHERE user_id = ? ORDER BY created_at DESC LIMIT ? OFFSET ?`,
		userID, limit, offset,
	)
	if err != nil {
		return nil, 0, fmt.Errorf("查询列表失败: %w", err)
	}
	defer rows.Close()

	// 2. 解析查询结果
	var albums []model.Album
	for rows.Next() {
		var album model.Album
		var isPublic int
		if err := rows.Scan(
			&album.ID, &album.UserID, &album.Name, &album.Description, &isPublic,
			&album.FolderPath, &album.CreatedAt,
		); err != nil {
			return nil, 0, fmt.Errorf("解析结果失败: %w", err)
		}
		album.IsPublic = isPublic == 1
		albums = append(albums, album)
	}

	// 检查行迭代错误
	if err := rows.Err(); err != nil {
		return nil, 0, fmt.Errorf("遍历记录失败: %w", err)
	}

	// 3. 查询总记录数
	var total int64
	err = config.DB.QueryRow(
		"SELECT COUNT(*) FROM albums WHERE user_id = ?",
		userID,
	).Scan(&total)
	if err != nil {
		return nil, 0, fmt.Errorf("查询总数失败: %w", err)
	}

	return albums, total, nil
}

// GetPublicAlbumsByUserID 分页查询指定用户的公开相册（适配bool类型的is_public）
func GetPublicAlbumsByUserID(userID int64, page, limit int) ([]model.Album, int64, error) {
	offset := (page - 1) * limit

	// 1. 查询公开相册列表（条件：用户ID匹配 + is_public = TRUE）
	query := `SELECT id, user_id, name, description, is_public, folder_path, created_at 
              FROM albums 
              WHERE user_id = ? AND is_public = TRUE  -- 布尔类型用TRUE/FALSE
              ORDER BY created_at DESC 
              LIMIT ? OFFSET ?`

	rows, err := config.DB.Query(query, userID, limit, offset)
	if err != nil {
		return nil, 0, fmt.Errorf("查询公开相册失败: %w", err)
	}
	defer rows.Close()

	// 2. 解析查询结果（直接扫描到bool字段）
	var albums []model.Album
	for rows.Next() {
		var album model.Album
		// 直接扫描到bool类型的is_public字段（无需int转bool）
		if err := rows.Scan(
			&album.ID, &album.UserID, &album.Name, &album.Description, &album.IsPublic,
			&album.FolderPath, &album.CreatedAt,
		); err != nil {
			return nil, 0, fmt.Errorf("解析相册信息失败: %w", err)
		}
		albums = append(albums, album)
	}

	// 检查行迭代错误
	if err := rows.Err(); err != nil {
		return nil, 0, fmt.Errorf("遍历相册记录失败: %w", err)
	}

	// 3. 查询总条数（条件同样使用is_public = TRUE）
	var total int64
	countQuery := `SELECT COUNT(*) FROM albums WHERE user_id = ? AND is_public = TRUE`
	if err := config.DB.QueryRow(countQuery, userID).Scan(&total); err != nil {
		return nil, 0, fmt.Errorf("查询公开相册总数失败: %w", err)
	}

	return albums, total, nil
}
